package com.stockz.equity.charting.painter;

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.stockz.equity.charting.display.Displayable;
import com.stockz.equity.charting.model.Shape;
import com.stockz.equity.charting.painter.axis.InformationAxisPainter;
import com.stockz.equity.charting.painter.axis.PriceAxisPainter;
import com.stockz.equity.charting.painter.axis.TimeAxisPainter;
import com.stockz.equity.charting.painter.axis.VolumeAxisPainter;
import com.stockz.equity.charting.painter.chart.RectangleVolumePainter;
import com.stockz.equity.charting.painter.indicator.IndicatorControlPainter;
import com.stockz.equity.charting.painter.indicator.IndicatorValuePainter;
import com.stockz.equity.charting.painter.shape.ShapePainter;
import com.stockz.equity.charting.util.Constant.OVERLAY;
import com.stockz.equity.charting.util.ContextUtil;
import com.stockz.equity.charting.view.StockChart;
import com.stockz.equity.charting.view.StockChartPanelState;
import com.stockz.equity.charting.view.StockChartPanelStructure;
import com.stockz.equity.charting.view.StockRectangle;
import com.stockz.equity.pattern.Painter;

@Component
@SuppressWarnings("rawtypes")
public class StockChartPanelPainter implements Painter<StockChart>{
	
	@Autowired private RectangleVolumePainter rectangleVolumePainter;
	@Autowired private GridPainter gridPainter;
	@Autowired private CrosshairPainter crosshairPainter;
	@Autowired private IndicatorControlPainter indicatorControlPainter;
	@Autowired private IndicatorValuePainter indicatorValuePainter;
	
	@Autowired private TimeAxisPainter timeAxisPainter;
	@Autowired private InformationAxisPainter informationAxisPainter;
	@Autowired private PriceAxisPainter priceAxisPainter;
	@Autowired private VolumeAxisPainter volumeAxisPainter;
	
	
	
	private Collection<ShapePainter> shapePainterCollection;
	
	@SuppressWarnings("unchecked")
	@Override
	public void paint(Graphics2D g, StockChart view, Rectangle rectangle) {
		StockChartPanelState state = view.getStockChartPanel().getStockChartPanelState();
		StockChartPanelStructure structure = view.getStockChartPanel().getStockChartPanelStructure();
		Rectangle chartRectangle = state.getChartRectangle();
		Rectangle drawingRectangle = state.getDrawingRectangle();
		Rectangle volumeRectangle = state.getVolumeRectangle();
		Rectangle priceRectangle = state.getPriceRectangle();
		g.setClip(null);
		timeAxisPainter.paint(g, view, new Rectangle(
				drawingRectangle.x,
				drawingRectangle.y+drawingRectangle.height,
				drawingRectangle.width,
				structure.getAxisTimeHeight()));
		
		informationAxisPainter.paint(g, view, new Rectangle(
				drawingRectangle.x,
				drawingRectangle.y - structure.getAxisInformationHeight(),
				drawingRectangle.width,
				structure.getAxisInformationHeight()));
		
		priceAxisPainter.paint(g, view, new Rectangle(
				priceRectangle.x - structure.getAxisPriceWidth(),
				priceRectangle.y,
				structure.getAxisPriceWidth(),
				priceRectangle.height));
		
		volumeAxisPainter.paint(g, view, new Rectangle(
				volumeRectangle.x + volumeRectangle.width,
				volumeRectangle.y,
				structure.getAxisVolumeWidth(),
				volumeRectangle.height));
		g.setClip(state.getVolumeRectangle());
		rectangleVolumePainter.paint(g, view, state.getVolumeRectangle());
		
		if(state.isGridVisible()){
			gridPainter.paint(g, view, state.getDrawingRectangle());
		}
		
		if(state.isCrosshairVisible()){
			crosshairPainter.paint(g, view, state.getDrawingRectangle());
		}
		
		g.setClip(chartRectangle);
		state.getStockChartPainter().paint(g, view, priceRectangle);
		
		for(StockRectangle rect : state.getStockRectangleSet()){
			rect.getOpaque().x = 0;
			rect.getOpaque().y = 0;
			for(Displayable  indicatorDisplay : rect.getDisplayableSet()){
				Painter<Displayable> painter = (Painter<Displayable>)ContextUtil.getApplicationContext().getBean(indicatorDisplay.getPainterClass());
				painter.paint(g, indicatorDisplay, indicatorDisplay.getRectangle());
				if(OVERLAY.PRICE.equals(indicatorDisplay.getOverlay())
						|| OVERLAY.VOLUME.equals(indicatorDisplay.getOverlay())){
					indicatorControlPainter.paint(g, indicatorDisplay, state.getChartRectangle());
				}else{
					indicatorControlPainter.paint(g, indicatorDisplay, indicatorDisplay.getRectangle());
				}
			}
			
			if(rect.equals(drawingRectangle) 
					|| rect.equals(chartRectangle) 
					|| rect.equals(state.getVolumeRectangle())
					|| rect.equals(state.getPriceRectangle())){
				continue;
			}else{
				g.setColor(view.getStockChartPanel().getStockChartPanelSkin().getIndicatorRectangleColor());
				g.setClip(null);
				g.drawRect( rect.x, rect.y, rect.width,rect.height);
				indicatorValuePainter.paint(g, rect.getDisplayableSet().iterator().next(), rect);
			}
		}
		
	/*	for(IndicatorDisplay  indicatorDisplay : state.getIndicatorDisplaySet()){
			Painter<IndicatorDisplay> painter = (Painter<IndicatorDisplay>)ContextUtil.getBean(indicatorDisplay.getPainterClass());
			painter.paint(g, indicatorDisplay, indicatorDisplay.getRectangle());
			indicatorControlPainter.paint(g, indicatorDisplay, indicatorDisplay.getRectangle());
			
			if(OVERLAY.INDEPENDENT.equals(indicatorDisplay.getOverlay())){
				g.setColor(view.getStockChartPanel().getStockChartPanelSkin().getIndicatorRectangleColor());
				g.setClip(null);
				g.drawRect( indicatorDisplay.getRectangle().x, indicatorDisplay.getRectangle().y, indicatorDisplay.getRectangle().width, indicatorDisplay.getRectangle().height);
			}
			
		}*/
		
		
		
		if(shapePainterCollection == null || shapePainterCollection.isEmpty()){
			shapePainterCollection = ContextUtil.getApplicationContext().getBeansOfType(ShapePainter.class).values();
		}
		
		for(ShapePainter painter : shapePainterCollection){
			for(Shape shape : state.getShapeSet()){
				if(shape.isVisible() && painter.supports(shape.getClass())){
					painter.paint(g, shape,view, rectangle);
				}
			}
		}
	}
}
